package tcpserver

import (
	"bytes"
	"log"
	"net"
	//"net/http"
	//"io"
	"time"

	"github.com/astaxie/beego"
)

type ConnCommmonHandler struct {
	//net.Conn
	c         net.Conn
	ischecked bool

	buf      *bytes.Buffer
	isReaded bool

	isKtv bool
}

func (h *ConnCommmonHandler) Read(p []byte) (n int, err error) {

	//log.Printf("ConnCommmonHandler, Reading, isktv = %v, len = %d, isReaded= %v", h.isKtv, len(p), h.isReaded)

	//if h.ischecked == false {
	//	h.checkType()
	//}

	if h.isReaded == false && h.buf != nil {
		h.isReaded = true

		n, err = h.buf.Read(p)
		//	log.Printf("read buffer, n = %d", n)
		return
	} else {
		n, err = h.c.Read(p)
		//	log.Printf("read conn, n = %d", n)
		return
	}

	return h.c.Read(p)
}

func (h *ConnCommmonHandler) Close() error {
	return h.c.Close()
}

func (h *ConnCommmonHandler) Write(p []byte) (n int, err error) {
	//log.Printf("ConnCommmonHandler, Writing = %d", len(p))
	return h.c.Write(p)
}

// 是否为HTTP协议
func (h *ConnCommmonHandler) newNetConn(c net.Conn) {

	h.c = c
	h.ischecked = false
	h.isReaded = false
	h.isKtv = true
	h.buf = bytes.NewBufferString("")

	h.checkType()

}

func (h *ConnCommmonHandler) checkType() {

	//	log.Printf("ConnCommmonHandler, Checking Type...")

	// 记录读取数据
	buffer := make([]byte, 1024*8)
	n, err := h.c.Read(buffer)
	//log.Printf("ConnCommmonHandler, from=%s, bytesCount = %d", h.c.RemoteAddr(), n)
	if err != nil {
		log.Printf("ConnCommmonHandler, something error")
		h.c.Close()
		return
	}

	h.ischecked = true
	h.isReaded = false

	if n > 0 {
		h.buf.Write(buffer[:n])
	}

	if n < 4 {
		//log.Printf("ConnCommmonHandler, need more data")
		//io.WriteString(h.c, "You are welcome")
		//h.c.Close()
		return
	}

	checkCode := uint32(buffer[0]) | uint32(buffer[1])<<8 | uint32(buffer[2])<<16 | uint32(buffer[3])<<24
	if checkCode == START_CODE {
		h.isKtv = true
	} else {
		h.isKtv = false
	}

	//	log.Printf("ConnCommmonHandler, checked, is ktv = %v", h.isKtv)
}

// 是否已经检查类型
func (h *ConnCommmonHandler) isChecked() bool {
	return h.ischecked
}

// LocalAddr returns the local network address.
func (h *ConnCommmonHandler) LocalAddr() net.Addr {
	return h.c.LocalAddr()
}

// RemoteAddr returns the remote network address.
func (h *ConnCommmonHandler) RemoteAddr() net.Addr {
	return h.c.RemoteAddr()
}

// SetDeadline sets the read and write deadlines associated
// with the connection. It is equivalent to calling both
// SetReadDeadline and SetWriteDeadline.
//
// A deadline is an absolute time after which I/O operations
// fail with a timeout (see type Error) instead of
// blocking. The deadline applies to all future I/O, not just
// the immediately following call to Read or Write.
//
// An idle timeout can be implemented by repeatedly extending
// the deadline after successful Read or Write calls.
//
// A zero value for t means I/O operations will not time out.
func (h *ConnCommmonHandler) SetDeadline(t time.Time) error {
	return h.c.SetDeadline(t)
}

// SetReadDeadline sets the deadline for future Read calls.
// A zero value for t means Read will not time out.
func (h *ConnCommmonHandler) SetReadDeadline(t time.Time) error {
	return h.c.SetReadDeadline(t)
}

// SetWriteDeadline sets the deadline for future Write calls.
// Even if write times out, it may return n > 0, indicating that
// some of the data was successfully written.
// A zero value for t means Write will not time out.
func (h *ConnCommmonHandler) SetWriteDeadline(t time.Time) error {
	return h.c.SetWriteDeadline(t)
}

//
func GotoHttpServer(rw net.Conn) {

	//log.Printf("GotoHttpServer")
	beego.BeeApp.Server.AddNewConn(rw)

}

/*

func (srv *Server) AddNewConn(rwc net.Conn) {
	c := srv.newConn(rwc)
	c.setState(c.rwc, StateNew) // before Serve can return
	go c.serve()
}

*/
